package com.cskaoyan.javase.variable4.precision2;

/**
 * @description: 浮点数的精度问题
 * @author: wuguidong@cskaoyan.onaliyun.com
 **/

/**
 * 浮点数的默认类型
 * 10.0
 * 1.3
 * 默认是double类型
 *
 *
 */
public class Demo {
    public static void main(String[] args) {
        //默认是double类型,可以用double接收
        double b = 10.0;
        //但是如果用float类型接收,这个时候会报错
        //怎么办?只要在这个字面值常量后面加一个F或者f,告诉编译器
        //我这个小数的字面值常量是一个float类型
        //建议用F,比较直观好看
        float f = 10.0F;

        System.out.println("---------------------");
        //精度问题
        //- 计算10/3.0
        //- 计算1-0.9
        double d = 10/3.0;
        System.out.println(d);
        double d1 = 1-0.9; //0.1
        System.out.println(d1);

        //进制的转换 十进制转换成二进制 除2
        //负数的十进制转换成二进制,先算出正数的二进制,然后取反+1
        //二进制怎么表示0.1?
        //把正十进制小数转换成二进制小数
        //正小数转换成二进制，用小数部分乘以2，取结果的整数部分(必然是1或者0)，
        //- 然后小数部分继续乘2
        //- 直到小数部分为0,或者已经达到了最大的位数
        //- 最终的结果（0.开头）正序排列
        /**
         * 0.1
         * 0.1*2 = 0.2  0
         * 0.2*2 = 0.4  0
         * 0.4*2 = 0.8  0
         * 0.8*2 = 1.6  1
         * 0.6*2 = 1.2  1
         * 0.2*2 = 0.4  0
         * 0.4*2 = 0.8  0
         *
         * 这个时候你已经发现了,它循环了,无限循环下去了
         * 它虽然是无限,但是我们的内存不是无限的,尤其是double,16位,于是忍痛截断
         * double就无法准确表示0.1
         *
         * 这就相当于十进制没有办法准确表示10/3,二进制也没办法表示0.1
         * 结论：浮点运算很少是精确的，只要是超过精度能表示的范围就会产生误差，生产环境慎用浮点数进行计算
         * 如果你开发的是对数字敏感的系统,比如说财务系统,银行之类 关于钱的 就不应该去使用浮点类型了
         * 最好的解决办法是用BigDecimal 替代float和double进行浮点数计算
         * 可以结合String 完美的计算小数
         *
         */


    }
}
